import json
import subprocess
import threading
import os
from util.FileUtil import FileUtil
from vo.Config import Config

class GradleUtil(object):
    def __init__(self):
        self.config = Config()
        self.android_path = f'{self.config.get_content('gitConfig')['address']}/Android/FAIS_6'
        self.gradle_file_path = f"{self.android_path}/app/build.gradle"
        self.gradle_copy_file_path = f"{self.android_path}/app/build_copy.gradle"
        self.mcs_file_path = f"{self.android_path}/mcs-services.json"
        self.mcs_copy_file_path = f"{self.android_path}/mcs-services_copy.json"
        self.implementation_pre = None
        self.assemble = None
        self.package_name = None
        self.honor_app_id = None
        self.m_modules = []
        self.process = None
        self.is_running = False
        self.client_id = None
        self.log_callback = None  # 添加回调函数属性
        self.build_path = f'{self.android_path}/app/build'
        self.download_path = self.config.get_content('serverConfig')['download_path']

    def set_gradle_params(self, params: dict, client_id=None):
        if self.is_running:
            return False
        else:
            self.client_id = client_id
            self.implementation_pre = params['implementationPre']
            self.assemble = params['assemble']
            self.package_name = params['packageName']
            self.honor_app_id = params['honorAppId']
            if params['modules'] != '':
                self.m_modules = params['modules'].split(',')
            else:
                self.m_modules = []
            return True

    def start_gradle(self):
        # 删除build文件夹
        FileUtil.delete_folder_files(self.build_path)
        self.build_mcs_file()
        self.build_temp_gradle_file()
        self.append_output('开始构建APK...')
        cmd = f'gradlew assemble{self.assemble}Release'

        threading.Thread(
            target=self.run_command,
            args=(cmd,),
            daemon=True
        ).start()

    def build_mcs_file(self):
        """读取msc-services.json文件内容并转换为字典"""
        try:
            self.append_output(f'正在备份{self.mcs_copy_file_path}文件...')
            with open(self.mcs_file_path, 'r', encoding='utf-8') as file:
                content = file.read()
                msc_data = json.loads(content)
                with open(self.mcs_copy_file_path, 'w', encoding='utf-8') as temp_file:
                    temp_file.write(content)
                print(msc_data['app_id'])
            self.append_output(f'正在构建新的{self.mcs_file_path}文件...')
            with open(self.mcs_file_path, 'w', encoding='utf-8') as file1:
                msc_data['app_id'] = self.honor_app_id
                msc_data['package_name'] = self.package_name
                json.dump(msc_data, file1, ensure_ascii=False)
            self.append_output(f'新的{self.mcs_file_path}文件构建完成...')
        except FileNotFoundError:
            self.append_output(f"未找到 {self.mcs_file_path} 文件")
        except json.JSONDecodeError:
            self.append_output(f"{self.mcs_file_path} 文件格式错误")
        except Exception as e:
            self.append_output(f"读取文件时发生错误：{str(e)}")

    # 读取build.gradle文件内容并写入临时文件
    def build_temp_gradle_file(self):
        try:
            self.append_output(f'正在备份{self.gradle_file_path}文件...')
            # 备份原始build.gradle文件
            with open(self.gradle_file_path, 'r', encoding='utf-8') as file:
                content = file.read()
                # 写入临时文件
                with open(self.gradle_copy_file_path, 'w', encoding='utf-8') as temp_file:
                    temp_file.write(content)
            self.append_output(f'{self.gradle_file_path}文件备份完成..')
            self.append_output(
                f'正在构建新的gradle文件,打包产品【{self.implementation_pre}】，打包模块【{self.m_modules}】')
            # 修改build.gradle文件的内容
            with open(self.gradle_file_path, 'r', encoding='utf-8') as file:
                content = file.read()
                # 构建新的gradle文件内容
                add_content = ['annotationProcessor libDependencies.glideCompiler']  # 新增的依赖
                if len(self.m_modules) > 0:
                    for module in self.m_modules:
                        add_content.append(f"\t{self.implementation_pre}Implementation project(':{module}')")

                if len(add_content) > 1:
                    datas = '\n'.join(add_content)
                    content = content.replace('annotationProcessor libDependencies.glideCompiler', datas)
            with open(self.gradle_file_path, 'w', encoding='utf-8') as file:
                file.write(content)

            self.append_output('gradle文件构建完成...')
        except FileNotFoundError:
            self.append_output(f"未找到 {self.gradle_file_path} 文件")
        except Exception as e:
            self.append_output(f"操作文件时发生错误：{str(e)}")

    def run_command(self, cmd):
        try:
            self.is_running = True
            original_dir = os.getcwd()
            os.chdir(self.android_path)
            self.process = subprocess.Popen(
                cmd,
                shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT,
                encoding='gbk',
                bufsize=1,
                universal_newlines=True
            )

            while True:
                line = self.process.stdout.readline()
                if not line and self.process.poll() is not None:
                    break
                if line:
                    self.append_output(line)

            if self.process.returncode != 0:
                self.append_output(f"打包失败")
                self.recover_mcs_file()
                self.recover_gradle_file()
            else:
                self.recover_mcs_file()
                self.recover_gradle_file()
                #  将打包好的apk文件移动到下载目录
                apk_files = FileUtil.find_files_by_extension(f'{self.build_path}/outputs/apk/{self.implementation_pre}/release','.apk')
                if len(apk_files) > 0:
                    file_name = FileUtil.get_filename(apk_files[0])
                    FileUtil.copy_file(apk_files[0], f'{self.download_path}/{self.implementation_pre}/{file_name}')
                    self.append_output(f'打包完成')
                    self.append_output(f'apk下载路径: http://192.168.0.10/Package/{self.implementation_pre}/{file_name}')
        except Exception as e:
            self.append_output(f"发生错误：{str(e)}")
            self.recover_mcs_file()
            self.recover_gradle_file()
        finally:
            self.is_running = False
            

    def recover_mcs_file(self):
        """恢复build.gradle文件"""
        try:
            self.append_output(f'正在恢复{self.mcs_file_path}文件...')
            with open(self.mcs_copy_file_path, 'r', encoding='utf-8') as file:
                content = file.read()
                with open(self.mcs_file_path, 'w', encoding='utf-8') as temp_file:
                    temp_file.write(content)
            self.append_output(f'{self.mcs_file_path}文件恢复完成...')
            if os.path.exists(self.mcs_copy_file_path):
                os.remove(self.mcs_copy_file_path)
                self.append_output(f'{self.mcs_copy_file_path}文件已删除')
        except FileNotFoundError as e:
            self.append_output(e)
        except Exception as e:
            self.append_output(f"操作文件时发生错误：{str(e)}")

    def recover_gradle_file(self):
        """恢复build.gradle文件"""
        try:
            self.append_output(f'正在恢复{self.gradle_file_path}文件...')
            with open(self.gradle_copy_file_path, 'r', encoding='utf-8') as file:
                content = file.read()
                with open(self.gradle_file_path, 'w', encoding='utf-8') as temp_file:
                    temp_file.write(content)
            self.append_output(f'{self.gradle_file_path}文件恢复完成...')
            if os.path.exists(self.gradle_copy_file_path):
                os.remove(self.gradle_copy_file_path)
                self.append_output(f'{self.gradle_copy_file_path}文件已删除')
        except FileNotFoundError as e:
            self.append_output(e)
        except Exception as e:
            self.append_output(f"操作文件时发生错误：{str(e)}")

    def set_log_callback(self, callback):
        """设置日志回调函数"""
        self.log_callback = callback

    def append_output(self, text):
        """输出日志到控制台和通过回调函数发送"""
        print(text)
        if self.log_callback:
            self.log_callback(text)
